package cn.krui.helper.tools;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.util.StringUtils;

/**
 * @author zc
 */
public class SecurityUtils {
  public static String base64Encode(String str) {
    return Base64.encodeBase64String(str.getBytes(Charset.forName("UTF-8")));
  }
  
  public static String base64Decode(String str) throws UnsupportedEncodingException {
    return new String(Base64.decodeBase64(str), "UTF-8");
  }
  
  public static String md5(String str) throws NoSuchAlgorithmException {
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    md5.update(str.getBytes(Charset.forName("UTF-8")));
    return toHexStr(md5.digest());
  }
  
  private static final char[] MCHARS = "0123456789ABCDEF".toCharArray();
  
  public static String toHexStr(byte[] data) {
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < data.length; i++) {
      builder.append(MCHARS[(data[i] & 0xFF) >> 4]);
      builder.append(MCHARS[data[i] & 0xF]);
    } 
    return builder.toString();
  }
  
  /**
   * encryptKey 为空时会取默认值
   * @param data
   * @param encryptKey
   * @return
   * @throws IllegalBlockSizeException
   * @throws BadPaddingException
   * @throws UnsupportedEncodingException
   * @throws NoSuchAlgorithmException
   * @throws InvalidKeyException
   * @throws NoSuchPaddingException
   */
  public static String aesEncode(String data, String encryptKey) throws IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException {
    if (StringUtils.isEmpty(encryptKey)) {
      encryptKey = "ec45dcb2-516c-11ea";
    }
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    kgen.init(128, new SecureRandom(encryptKey.getBytes()));
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(1, new SecretKeySpec(kgen.generateKey().getEncoded(), "AES"));
    return Base64.encodeBase64String(cipher.doFinal(data.getBytes("UTF-8")));
  }
  
  /**
   * encryptKey 为空时会取默认值
   * @param data
   * @param encryptKey
   * @return
   * @throws GeneralSecurityException
   * @throws UnsupportedEncodingException
   */
  public static String aesDecode(String data, String encryptKey) throws GeneralSecurityException, UnsupportedEncodingException {
    if (StringUtils.isEmpty(encryptKey)) {
      encryptKey = "ec45dcb2-516c-11ea";
    }
    byte[] content = Base64.decodeBase64(data);
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    kgen.init(128, new SecureRandom(encryptKey.getBytes()));
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(2, new SecretKeySpec(kgen.generateKey().getEncoded(), "AES"));
    return new String(cipher.doFinal(content), "UTF-8");
  }
}
